package common

import (
	"gitee.com/aldrice/monitor/configs"
	"gitee.com/aldrice/monitor/internal/router"
	"github.com/dgrijalva/jwt-go"
	"github.com/labstack/echo/v4"
	"go.uber.org/zap"
	"strconv"
	"strings"
	"time"
)

func CreateSign(ID int, last int64, key []byte, length time.Duration) (string, error) {
	if 0 == last {
		last = time.Now().Unix()
	}
	claims := jwt.StandardClaims{
		NotBefore: last,
		IssuedAt:  time.Now().Unix(),
		ExpiresAt: time.Now().Add(length * time.Hour).Unix(),
		Audience:  strconv.Itoa(ID),
	}
	return jwt.NewWithClaims(jwt.SigningMethodHS256, claims).SignedString(key)
}

var (
	errInvalidAuthHeader = router.ApiException(401, 11001, "用户未登录")
	errInvalidAuthToken  = router.ApiException(401, 11002, "用户登录状态已失效，请重新登录")
	errParseUserIDFailed = router.ApiException(401, 11003, "用户登录信息异常，请重新登录")
)

func JWT(next echo.HandlerFunc) echo.HandlerFunc {
	return func(ec echo.Context) error {
		c := ec.(*router.Context)
		h := c.Request().Header.Get(echo.HeaderAuthorization)
		if !strings.HasPrefix(h, "Bearer ") {
			return errInvalidAuthHeader
		}

		claim := &jwt.StandardClaims{}
		token, err := jwt.ParseWithClaims(h[7:], claim, configs.JwtSecureKey)
		if err != nil || !token.Valid {
			return errInvalidAuthToken
		}
		uid, err := strconv.Atoi(claim.Audience)
		if err != nil {
			c.MyLogger().Error("parse user id failed", zap.String("uid", claim.Audience))
			return errParseUserIDFailed
		}
		c.SetUID(uid)
		return next(c)
	}
}
